#include "../mainctrl.h"
#include "CClanEntry.h"
#include "CClanEntry.h"

int CClanEntryShop::ReNewShopItem (unsigned char ucClanLevel)
{
    _iLastRefreshTime = CMainCtrl::m_pstMain->m_iNow;

    unsigned char ucClanShopId;
    int iRet = CMainCtrl::m_pstMain->m_stShopMgr._stRoleToShopId.GetClanShopId(ucClanLevel, ucClanShopId);
    if (iRet)
    {
        CT_ERROR(("%d, %d", iRet, ucClanLevel));
        return iRet;
    }

    CClanShopConfigUnit stConfigData;
    iRet = CMainCtrl::m_pstMain->m_stShopMgr._stClanShopConfig.GetConfigData(ucClanShopId, stConfigData);
    if (iRet)
    {
        CT_ERROR(("%d, %d", iRet, ucClanShopId));
        return iRet;
    }

    CClanBuildConfig stBuildConfig;
    iRet = CMainCtrl::m_pstMain->m_stClanMgr._stClanConfig.GetClanBuildConfig(ucClanLevel, stBuildConfig);
    if (iRet)
    {
        CT_ERROR(("%d, %d", iRet, ucClanLevel));
        return iRet;
    }

    int iMaxItemInShop = stBuildConfig._ucShopItemCnt;
    _astItems.m_iUsedCount = iMaxItemInShop;
    for (int i = 0; i < iMaxItemInShop; i++)
    {
        CDropItemData stDropItemData;
        do
        {
            unsigned char ucPos;
            iRet = CMainCtrl::m_pstMain->m_stShopMgr._stClanShopConfig._stClanItemDrop.DropShopItem(ucClanShopId, ucPos);
            if (iRet)
            {
                CT_ERROR(("clan shop drop item, usPlayerLevel: %u, iRet: %d.", ucClanLevel, iRet));
                return iRet;
            }

            CT_TRACE(("clan shop drop item, level: %u, ucpos: %u.", ucClanLevel, ucPos));

            CClanShopItemConfig stItemCfg;
            iRet = stConfigData.GetShopItem(ucPos, stItemCfg);
            CHECK_RETURN(iRet);

            iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetDropItemData(0, stItemCfg._ucShopItemType, stItemCfg._usItemConfigId,
                stItemCfg._szShopItemSubType.Get(), COMM_MOD, stItemCfg._ucShopCount, stDropItemData);
            if (iRet)
            {
                CT_ERROR(("clan shop get drop item, usPlayerLevel: %u,  ucPos %u, iRet: %u.",
                    ucClanLevel, ucPos, iRet));
                return iRet;
            }
        } while (HasSameItem (stDropItemData));

        CShopItemConfig & stShopItem = _astItems[i];
        stShopItem.Clear();
        stShopItem._ucItemType = stDropItemData._ucItemType;
        stShopItem._usItemConfigID = stDropItemData._usItemConfigID;
        stShopItem._usItemCount = (unsigned short)stDropItemData._iItemCount;
        stShopItem._ucBuyType = ITEM_TYPE_CONTRIBUTION;
        stShopItem._ucExchangeItemType  = 0;
        stShopItem._usExchangeItemID      = 0;
        iRet = CMainCtrl::m_pstMain->m_stItemMgr.GetItemPrice(stShopItem._ucItemType, stShopItem._usItemConfigID,
            stShopItem._usItemCount, ITEM_BUY_PRICE_CONTRI, stShopItem._iExchangeItemCount);
        if (iRet)
        {
            CT_ERROR(("get item price: %u, %u, %u.",
                stShopItem._ucItemType, stShopItem._usItemConfigID, iRet));
            return iRet;
        }
    }
    return 0;
}

bool CClanEntryShop::HasSameItem (CDropItemData & stItem)
{
    for (int i = 0; i < _astItems.Size(); i++)
    {
        if (stItem._ucItemType == _astItems[i]._ucItemType
            && stItem._usItemConfigID == _astItems[i]._usItemConfigID)
        {
            return true;
        }
    }

    return  false;
}

int CClanEntryShop::GetShopItem (unsigned char ucPos, CShopItemConfig & stShopItem)
{
    if (ucPos > _astItems.Size())
    {
        CT_ERROR(("%d", ucPos));
        return ERROR_SHOP_NO_SELL_ITEM;
    }

    stShopItem = _astItems[ucPos];
    return 0;
}

int CClanEntry::GetClanMember (unsigned int uiGid, CClanMember & stMember)
{
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._uiGid == uiGid)
        {
            stMember = _astClanMember[i];
            return 0;
        }
    }

    return ERROR_CLAN_MEMBER_NOT_EXIST;
}

int CClanEntry::AddNewMember (const CClanMember & stMember)
{
    if (IsMemberFull())
    {
        return ERROR_CLAN_MEMBER_FULL;
    }

    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._uiGid == stMember._uiGid)
        {
            return ERROR_CLAN_MEMBER_ALREADY;
        }
    }

    _astClanMember.AddOneItem(stMember);
    if (CLAN_MEMBER_NORM == stMember._ucClanTitle)
    {
        RefreshElite();
    }

    return 0;
}

int CClanEntry::RemoveMember (unsigned int uiGid)
{
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._uiGid == uiGid)
        {
            _astClanMember.DelOneItem(i);

            RefreshElite();
            return 0;
        }
    }

    return ERROR_CLAN_MEMBER_NOT_EXIST;
}

int CClanEntry::GetMemberCount (unsigned char ucTitle)
{
    int iCount = 0;
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (ucTitle == _astClanMember[i]._ucClanTitle)
        {
            iCount++;
        }
    }

    return iCount;
}

int CClanEntry::GetMaxMemberCount ()
{
#if 0
    int iCount = 15 + (_ucClanLevel/5);

    if (iCount > MAX_CLAN_MEMBER_COUNT)
    {
        iCount = MAX_CLAN_MEMBER_COUNT;
    }

    return iCount;
#endif
    return MAX_CLAN_MEMBER_COUNT;
}

int CClanEntry::GetClanLeader (unsigned int & uiGid)
{
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._ucClanTitle == CLAN_MEMBER_LEADER)
        {
            uiGid = _astClanMember[i]._uiGid;

            return 0;
        }
    }

    CT_ERROR(("%d", _uiClanId));

    return ERROR_CLAN_LEADER_NOT_EXIST;
}

int CClanEntry::GetClanVice (unsigned int & uiVice1, unsigned int & uiVice2)
{
    int iCount = 0;
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._ucClanTitle == CLAN_MEMBER_VICE)
        {
            if (iCount == 0)
            {
                uiVice1 = _astClanMember[i]._uiGid;
            }
            else
            {
                uiVice2 = _astClanMember[i]._uiGid;
            }
        }
    }

    return 0;
}

int CClanEntry::SetMemberTitle (unsigned int uiGid, unsigned char ucTitle)
{
    if (ucTitle <= CLAN_MEMBER_NONE || ucTitle >= CLAN_MEMBER_TYPEMAX)
    {
        return ERROR_CLAN_MEMBER_TITLE;
    }

    int iCount = GetMemberCount(ucTitle);
    if ( (CLAN_MEMBER_VICE == ucTitle)
        && (iCount >= CLAN_VICE_LEADER_NUM))
    {
        return ERROR_CLAN_VICE_FULL;
    }

    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._uiGid == uiGid)
        {
            _astClanMember[i]._ucClanTitle = ucTitle;

            if ((CLAN_MEMBER_VICE == ucTitle)
                || (CLAN_MEMBER_NORM == ucTitle))
            {
                RefreshElite();
            }

            return 0;
        }
    }

    return ERROR_CLAN_MEMBER_NOT_EXIST;
}

int CClanEntry::AddJoinReq (unsigned int uiGid)
{
    //����������������?
    if (_astJoinReq.Size() >= MAX_CLAN_JOIN_REQ_NUM)
    {
        return ERROR_CLAN_JOIN_REQ_FULL;
    }

    //�����Ա����?
    if (IsMemberFull())
    {
        return ERROR_CLAN_MEMBER_FULL;
    }

    //�Ѿ��Ǽ����Ա��
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._uiGid == uiGid)
        {
            return ERROR_CLAN_MEMBER_ALREADY;
        }
    }

    //�Ѿ������?
    for (int i = 0; i < _astJoinReq.Size(); i++)
    {
        if (_astJoinReq[i] == uiGid)
        {
            return ERROR_CLAN_REPEATED_REQ;
        }
    }

    _astJoinReq.AddOneItem(uiGid);
    return 0;
}

int CClanEntry::DelJoinReq (unsigned int uiGid)
{
    for (int i = 0; i < _astJoinReq.Size(); i++)
    {
        if (_astJoinReq[i] == uiGid)
        {
            _astJoinReq.DelOneItem(i);
            return 0;
        }
    }

    return ERROR_JOIN_CLAN_REQ_NONE;
}

int CClanEntry::AddTodayContri (unsigned int uiGid, int iContribution)
{
    if (iContribution == 0)
    {
        return 0;
    }

    if (iContribution < 0)
    {
        CT_ERROR(("%d", iContribution));
        return 0;
    }

    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._uiGid == uiGid)
        {
            if (!CTTimeUtils::IsSameDay(CMainCtrl::m_pstMain->m_iNow, _astClanMember[i]._iLastCalcTime))
            {
                _astClanMember[i]._iTodayContri = 0;
            }

            _astClanMember[i]._iTodayContri += iContribution;
            _astClanMember[i]._iAccumContri += iContribution;
            _iConstruction += iContribution;
            _astClanMember[i]._iLastCalcTime = CMainCtrl::m_pstMain->m_iNow;

            RefreshElite();

            return 0;
        }
    }

    return ERROR_CLAN_MEMBER_NOT_EXIST;
}

int CClanEntry::AddLog (CClanLog & stLog)
{
    if (_astClanLog.Size() >= MAX_CLAN_LOG_NUM)
    {
        _astClanLog.ShiftDelOneItem(0);
    }

    stLog._iTime = CMainCtrl::m_pstMain->m_iNow;
    _astClanLog.AddOneItem(stLog);
    return 0;
}

void CClanEntry::RefreshElite()
{
    //�������峤�͸��峤, �����ܹ��׶�����ǰ5����Ϊ��Ӣ

    CTArray<CClanMember, CLAN_NORM_MEMBER_NUM> auiNormal;
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        CClanMember & stMember = _astClanMember[i];
        if (stMember._ucClanTitle == CLAN_MEMBER_LEADER
            || stMember._ucClanTitle == CLAN_MEMBER_VICE)
        {
            continue;
        }

        //�����֮ǰ�ľ�Ӣ��Ա
        if (stMember._ucClanTitle == CLAN_MEMBER_ELITE)
        {
            stMember._ucClanTitle = CLAN_MEMBER_NORM;
        }

        auiNormal.AddOneItem(stMember);
    }

    if (auiNormal.Size() > CLAN_ELITE_NUM)
    {
        //ѡ������ �鿴�ܷ��Ϊ��Ӣ?
        for (int i = 0; i < CLAN_ELITE_NUM; i++)
        {
            int iEliteIndex = i;
            for (int k = i + 1; k < auiNormal.Size(); ++k)
            {
                CClanMember & stElite = auiNormal[iEliteIndex];
                CClanMember & stMember = auiNormal[k];

                if ( stMember._iAccumContri >  stElite._iAccumContri ||
                    (stMember._iAccumContri == stElite._iAccumContri && stMember._uiGid < stElite._uiGid))
                {
                    iEliteIndex = k;
                }
            }

            if (iEliteIndex != i)
            {
                CClanMember stTmp = auiNormal[i];
                auiNormal[i] = auiNormal[iEliteIndex];
                auiNormal[iEliteIndex] = stTmp;
            }
        }
    }

    //(��0��Ԫ�أ��ܹ���ֵ���)
    int iEliteNum = CT_MIN(CLAN_ELITE_NUM, (auiNormal.Size()));
    for (int i = 0; i < iEliteNum; ++i)
    {
        SetMemberTitle(auiNormal[i]._uiGid, CLAN_MEMBER_ELITE);
    }
}

void CClanEntry::GetMostContriGid (unsigned char ucTitle, unsigned int & uiGid)
{
    uiGid = 0;
    int iMostContri = -1;
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._ucClanTitle == ucTitle)
        {
            int iIndex = CMainCtrl::m_pstMain->m_stPlayerSnsCommInfoHash.HashFind(_astClanMember[i]._uiGid);
            if (iIndex < 0)
            {
                CT_ERROR (("%d", _astClanMember[i]._uiGid));
                continue;
            }
            CPlayerSnsCommInfo & stPlayerSnsCommInfo = CMainCtrl::m_pstMain->m_stPlayerSnsCommInfoHash[iIndex];

            int iOffLineTime = stPlayerSnsCommInfo.GetOffLineTime(CMainCtrl::m_pstMain->m_iNow);
            if (iOffLineTime >= MAX_CLAN_RECOMMD_TIME)
            {
                continue;
            }

            int iAccumContri = _astClanMember[i]._iAccumContri;

            if (iAccumContri > iMostContri)
            {
                uiGid = _astClanMember[i]._uiGid;
                iMostContri = iAccumContri;
            }

            if (iAccumContri == iMostContri && _astClanMember[i]._uiGid < uiGid)
            {
                uiGid = _astClanMember[i]._uiGid;
                iMostContri = iAccumContri;
            }
        }
    }
}

void CClanEntry::SetAuctionBuffTime (int iEndTime)
{
    _iAuctionBuffTime = iEndTime;
}

int CClanEntry::GetAuctionBuffEndTime ()
{
    return _iAuctionBuffTime;
}

bool CClanEntry::IsMemberFull ()
{
    if (_astClanMember.Size() >= GetMaxMemberCount())
    {
        return true;
    }

    return false;
}

bool CClanEntry::HasThisMember (unsigned int uiGid)
{
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (uiGid == _astClanMember[i]._uiGid)
        {
            return true;
        }
    }

    return false;
}

void CClanEntry::UpdateDiceRank (unsigned int uiGid, int iBestWeekPos)
{
    //没有参加过闯关活动的不参与排行
    if (iBestWeekPos <= 0)
    {
        return ;
    }

    CDiceRank & stDiceRank = _stDiceRank;

    int iRankIndex = stDiceRank.GetRankIndex(uiGid);
    if (iRankIndex < 0)
    {
        CDiceRankUnit stNewUnit;
        stNewUnit._uiGid = uiGid;
        stNewUnit._iBeseWeekPos = iBestWeekPos;

        if (stDiceRank._stRank.Size() < stDiceRank._stRank.GetCount())
        {
            iRankIndex = stDiceRank._stRank.AddOneItem(stNewUnit);
        }
        else
        {
            iRankIndex = MAX_DICE_RANK_SIZE -1;
            if (iBestWeekPos <= stDiceRank._stRank[iRankIndex]._iBeseWeekPos)
            {
                return ;
            }

            stDiceRank._stRank[iRankIndex]._uiGid = uiGid;
            stDiceRank._stRank[iRankIndex]._iBeseWeekPos = iBestWeekPos;
        }
    }
    else
    {
        stDiceRank._stRank[iRankIndex]._iBeseWeekPos = iBestWeekPos;
    }

    //排序
    for (int i = iRankIndex - 1; i >= 0; --i)
    {
        CDiceRankUnit & stPrevUnit = stDiceRank._stRank[i];
        CDiceRankUnit & stCurUnit = stDiceRank._stRank[i+1];

        if (stPrevUnit._iBeseWeekPos >= stCurUnit._iBeseWeekPos)  //冒泡
        {
            return ;
        }

        CDiceRankUnit stTmp = stPrevUnit;
        stPrevUnit = stCurUnit;
        stCurUnit = stTmp;
    }
}

int CClanEntry::GetTodayRecuitCnt (int iNowTime)
{
    return _usDailyRecruitCnt.Get(iNowTime);
}

void CClanEntry::AddTodayRecuitCnt (int iNowTime)
{
    _usDailyRecruitCnt.Add(1, iNowTime);
}

void CClanEntry::GetManager (T_CLAN_MANAGER & stManager)
{
    stManager.Clear();
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._ucClanTitle == CLAN_MEMBER_VICE
            || _astClanMember[i]._ucClanTitle == CLAN_MEMBER_LEADER)
        {
            stManager.AddOneItem (_astClanMember[i]._uiGid);
        }
    }
}

bool CClanEntry::HasLeader  ()
{
    for (int i = 0; i < _astClanMember.Size(); i++)
    {
        if (_astClanMember[i]._ucClanTitle == CLAN_MEMBER_LEADER)
        {
            return true;
        }
    }

    return false;
}
